import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { NestExpressApplication } from "@nestjs/platform-express";
import { HttpExceptionFilter } from "./core/filter/http-exception/http-exception.filter";
import { TransformInterceptor } from "./core/interceptor/transform/transform.interceptor";
import { ValidationPipe } from "@nestjs/common";
import { existsSync, mkdirSync } from "fs";
import helmet from "helmet";
import rateLimit from "express-rate-limit";
import * as compression from "compression";
import * as express from "express";
import { WINSTON_MODULE_NEST_PROVIDER } from "nest-winston";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
// import * as cors from "cors";
// 定义静态文件路径
const filePath = "public";
// 配置CORS策略，允许特定的域名访问
// const corsOptions = {
// 	origin: "", // 允许的域名
// 	methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
// 	credentials: true // 如果需要发送cookie等凭证
// };
// 启动函数
async function bootstrap() {
	// 创建NestExpressApplication实例
	const app = await NestFactory.create<NestExpressApplication>(AppModule);

	// 添加代理，以获得正确的ip
	app.set("trust proxy", 1);

	// 压缩
	app.use(compression());

	// 请求限制
	app.use(
		rateLimit({
			windowMs: 60 * 1000, // 1分钟
			max: 100 // 限制每个IP每个窗口100个请求
		})
	);
	app.use(express.json({ limit: "10MB" }));
	// 全局路由前缀
	app.setGlobalPrefix("api");

	// 注册全局错误的过滤器
	app.useGlobalFilters(new HttpExceptionFilter());

	// 全局注册拦截器
	app.useGlobalInterceptors(new TransformInterceptor());

	// 设置api接口验证管道
	app.useGlobalPipes(new ValidationPipe());

	// 启用CORS
	// app.use(cors(corsOptions));
	// 防止跨站脚本攻击
	// same-site：资源只能被同源请求访问。
	// cross-origin：资源可以被跨域请求访问。
	app.use(
		helmet({
			crossOriginResourcePolicy: { policy: "same-site" }
		})
	);
	// 配置静态路径
	app.useStaticAssets("public", {
		prefix: "/static/" //设置虚拟路径
	});

	// 设置swagger文档
	const config = new DocumentBuilder()
		.setTitle("管理后台")
		.setDescription("管理后台接口文档")
		.setVersion("1.0")
		.addBearerAuth()
		.build();
	const document = SwaggerModule.createDocument(app, config);
	SwaggerModule.setup("docs", app, document);

	// 如果静态文件路径不存在，则创建
	if (!existsSync(filePath)) {
		mkdirSync(filePath);
	}

	// 使用日志记录器
	app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));

	// 监听8000端口
	await app.listen(8000);
}
bootstrap();
